﻿using System.Diagnostics;

namespace Devonline.Core;

public static class DelegateExtensions
{
    /// <summary>
    /// 执行方法并返回执行时间
    /// </summary>
    /// <param name="action"></param>
    /// <returns></returns>
    public static TimeSpan WatchAction(this Action action)
    {
        if (action == null)
        {
            throw new ArgumentNullException(nameof(action));
        }

        Stopwatch watch = Stopwatch.StartNew();
        action();
        return watch.Elapsed;
    }
    /// <summary>
    /// 执行方法并返回执行时间
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    /// <param name="t"></param>
    /// <returns></returns>
    public static TimeSpan WatchAction<T>(this Action<T> action, T t)
    {
        if (action == null)
        {
            throw new ArgumentNullException(nameof(action));
        }

        Stopwatch watch = Stopwatch.StartNew();
        action(t);
        return watch.Elapsed;
    }
    /// <summary>
    /// 执行任务并返回执行时间
    /// </summary>
    /// <param name="exec"></param>
    /// <returns></returns>
    public static async Task<TimeSpan> WatchActionAsync(this Func<Task> exec)
    {
        if (exec == null)
        {
            throw new ArgumentNullException(nameof(exec));
        }

        var watch = Stopwatch.StartNew();
        await exec().ConfigureAwait(false);
        return watch.Elapsed;
    }
    /// <summary>
    /// 执行任务并返回执行时间
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="task"></param>
    /// <param name="t"></param>
    /// <returns></returns>
    public static async Task<TimeSpan> WatchActionAsync<T>(this Func<T, Task> task, T t)
    {
        if (task == null)
        {
            throw new ArgumentNullException(nameof(task));
        }

        Stopwatch watch = Stopwatch.StartNew();
        await task(t).ConfigureAwait(true);
        return watch.Elapsed;
    }
}